<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>重要的内置关系</title>
    <script type="text/javascript" src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
    <!--
	    1.一个重要的内置关系：VueComponent.prototype.__proto__ === Vue.prototype
		2.为什么要有这个关系：让组件实例对象（vc）可以访问到 Vue原型上的属性、方法。
	-->
    <div id="root">
        <school></school>
    </div>
</body>
<script type="text/javascript">
    // 定义一个构造函数
    function Demo() {
        this.a = 1;
        this.b = 2;
    }
    // 创建一个 Demo 的实例对象
    const d = new Demo();
    // 显式原型属性
    console.log(Demo.prototype);
    console.log(d.__proto__);
    console.log(Demo.prototype === d.__proto__);

    // 程序员通过显式原型属性操作原型对象，追加一个 x 属性，值为 99
    Demo.prototype.x = 99;
    console.log('@', d);
    console.log('#', Demo);

    Vue.prototype.x = 99;

    //定义school组件
    const school = Vue.extend({
        name:'school',
        template:`
				<div>
					<h2>学校名称：{{name}}</h2>
					<h2>学校地址：{{address}}</h2>
					<button @click="showX">点我输出x</button>
				</div>
			`,
        data(){
            return {
                name:'尚硅谷',
                address:'北京'
            }
        },
        methods: {
            showX(){
                console.log(this.x)
            }
        },
    });

    //创建一个vm
    const vm = new Vue({
        el:'#root',
        data:{
            msg:'你好'
        },
        components:{school}
    });

    /**
     * 对应名称：
     * -- prototype：原型
     * -- __proto__：原型链
     *
     * 从属关系：
     * prototype -> 函数的一个属性：对象 {}
     * __proto__ -> 对象的一个属性：对象 {}
     * 对象的 __proto__ 保存着该对象的构造函数的 prototype
     *
     * 在 js 中，函数可以有属性。 每个函数都有一个特殊的属性叫作原型（prototype）
     * 每个实例对象拥有一个原型对象 __proto__，通过原型对象一级一级的往上找的这个过程就是原型链
     *
     */

    function Test() {}
    console.log(Test.prototype);

    Test.prototype.b = 2;
    Test.prototype.c = 222;
    Object.prototype.c = 3;

    const test = new Test();
    console.log(test.__proto__);
    console.log(Test.prototype === test.__proto__);

    console.log(Test.prototype.__proto__ === Object.prototype);
    console.log(Object.prototype.__proto__); // null

    /**
     * test {
     *     b: 333,
     *     a: 1,
     *     __proto__: Test.prototype = {
     *         c: 222,
     *         b: 2,
     *         __proto__: Object.prototype = {
     *             c: 3
     *             无 __proto__
     *         }
     *     }
     * }
     */

    // Function Object：函数，对象
    // const Test = new Function()
    // Test 对象的构造函数是 Function
    console.log(Test.__proto__ === Function.prototype);

    // Function 对象的构造函数就是它自己
    console.log(Function.__proto__);
    console.log(Function.prototype);
    console.log(Function.__proto__ === Function.prototype);

    // const obj = {}
    // const obj = new Object(); // function
    console.log(typeof Object);
    // Object 对象的构造函数是 Function
    console.log(Object.__proto__ === Function.prototype);
    console.log(Object.__proto__ === Function.__proto__);

    console.log('-------------------------');
    console.log(test.hasOwnProperty('a'));
    console.log(test.hasOwnProperty('b'));
    console.log(test.hasOwnProperty('c'));

    console.log('-------------------------');
    console.log('a' in test);
    console.log('b' in test);
    console.log('c' in test);

</script>
</html>